// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shell/browser/lib/power_observer_ohos.h"

#include <unistd.h>
#include <uv.h>
#include <utility>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "device/bluetooth/dbus/bluez_dbus_thread_manager.h"

namespace {

const char kLogindServiceName[] = "org.freedesktop.login1";

base::FilePath::StringType GetExecutableBaseName() {
  return base::CommandLine::ForCurrentProcess()
      ->GetProgram()
      .BaseName()
      .value();
}

}  // namespace

namespace electron {

PowerObserverOhos::PowerObserverOhos(
    base::PowerSuspendObserver* suspend_observer)
    : suspend_observer_(suspend_observer),
      lock_owner_name_(GetExecutableBaseName()) {}

PowerObserverOhos::~PowerObserverOhos() = default;

void PowerObserverOhos::OnLoginServiceAvailable(bool service_available) {
  if (!service_available) {
    LOG(WARNING) << kLogindServiceName << " not available";
    return;
  }
  // Take sleep inhibit lock
  BlockSleep();
}

void PowerObserverOhos::BlockSleep() {}

void PowerObserverOhos::UnblockSleep() {
  sleep_lock_.reset();
}

void PowerObserverOhos::BlockShutdown() {}

void PowerObserverOhos::UnblockShutdown() {
  if (!shutdown_lock_.is_valid()) {
    LOG(WARNING)
        << "Trying to unsubscribe to shutdown without being subscribed";
    return;
  }
  shutdown_lock_.reset();
}

void PowerObserverOhos::SetShutdownHandler(
    base::RepeatingCallback<bool()> handler) {
  LOG(ERROR) << __FUNCTION__ << "You need to implement this function!!!";
  // In order to delay system shutdown when e.preventDefault() is invoked
  // on a powerMonitor 'shutdown' event, we need an org.freedesktop.login1
  // shutdown delay lock. For more details see the "Taking Delay Locks"
  // section of https://www.freedesktop.org/wiki/Software/systemd/inhibit/
  if (handler && !should_shutdown_) {
    BlockShutdown();
  } else if (!handler && should_shutdown_) {
    UnblockShutdown();
  }
  should_shutdown_ = std::move(handler);
}

void PowerObserverOhos::OnPrepareForSleep(std::string event) {
  if (event == "suspend") {
    suspend_observer_->OnSuspend();
    UnblockSleep();
  } else if (event == "resume") {
    BlockSleep();
    suspend_observer_->OnResume();
  }
}

void PowerObserverOhos::OnSignalConnected(const std::string& /*interface*/,
                                          const std::string& signal,
                                          bool success) {
  LOG_IF(WARNING, !success) << "Failed to connect to " << signal;
}

}  // namespace electron
